package com.sc.nft.dao;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Sets;
import com.sc.nft.entity.vo.SubscribeProductListVo;
import com.sc.nft.enums.ProductInfoSubscribeScheduleEnum;
import com.sc.nft.entity.vo.ProductIdAndMaxSubscribeByUserIdAndCountVO;
import com.sc.nft.enums.ProductInfoSubscribeScheduleEnum;
import com.sc.nft.enums.ProductInfoSubscribeSourceEnum;
import com.sc.nft.mapper.DigitalCollectionProductInfoSubscribeCodeMapper;
import com.sc.nft.entity.DigitalCollectionProductInfoSubscribeCode;
import com.sc.nft.entity.dto.DigitalCollectionProductInfoSubscribeCodeDTO;
import com.sc.nft.entity.vo.DigitalCollectionProductInfoSubscribeCodeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户申购码(DigitalCollectionProductInfoSubscribeCode)表Dao层
 *
 * @author 王伟成
 * @since 2024-05-15 18:32:39
 */
@Slf4j
@Repository
public class DigitalCollectionProductInfoSubscribeCodeDao extends ServiceImpl<DigitalCollectionProductInfoSubscribeCodeMapper, DigitalCollectionProductInfoSubscribeCode> {

    public Page<DigitalCollectionProductInfoSubscribeCodeVo> getSubscribeCodePage(DigitalCollectionProductInfoSubscribeCodeDTO request) {
        if(ObjectUtil.isNull(request.getActivityStatus())){
            return baseMapper.getSubscribeCodePage(request.toMp(),request.getFirstTitle(),null);
        }
        return baseMapper.getSubscribeCodePage(request.toMp(),request.getFirstTitle(),request.getActivityStatus().getCode());
    }

    public Set<String> getListByUserId(Long userId, Set<String> subscribeCodes) {
        LambdaQueryWrapper<DigitalCollectionProductInfoSubscribeCode> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getUserId, userId);
        wrapper.in(DigitalCollectionProductInfoSubscribeCode::getSubscribeCode, subscribeCodes);
        List<DigitalCollectionProductInfoSubscribeCode> digitalCollectionProductInfoSubscribeCodes = baseMapper.selectList(wrapper);
        if( Objects.isNull(digitalCollectionProductInfoSubscribeCodes) || digitalCollectionProductInfoSubscribeCodes.size() ==0) {
            return Sets.newHashSet();
        }
        return digitalCollectionProductInfoSubscribeCodes.stream().map(DigitalCollectionProductInfoSubscribeCode::getSubscribeCode).collect(Collectors.toSet());
    }
    public void drawLots(Long productId, Integer sumCount,Set<Long>excludeUserId) {
        baseMapper.drawLots(productId,sumCount,excludeUserId);
    }
    public List<ProductIdAndMaxSubscribeByUserIdAndCountVO> getProductIdAndMaxSubscribeByUserIdAndCount(Long productId, Integer maxSubscribe,Set<Long>excludeUserId) {
        return baseMapper.getProductIdAndMaxSubscribeByUserIdAndCount(productId,maxSubscribe,excludeUserId);
    }
    public Boolean takeOut(Long userId, Long productId, Integer takeOut) {
        LambdaUpdateWrapper<DigitalCollectionProductInfoSubscribeCode> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getUserId, userId);
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getProductId, productId);
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getSchedule, ProductInfoSubscribeScheduleEnum.WINED);
        wrapper.set(DigitalCollectionProductInfoSubscribeCode::getSchedule, ProductInfoSubscribeScheduleEnum.NOT_WIN);
        wrapper.last("limit "+takeOut);
        Integer i = baseMapper.update(new DigitalCollectionProductInfoSubscribeCode(),wrapper);
        if (i==takeOut) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
    public Boolean updateSchedule(Long productId) {
        LambdaQueryWrapper<DigitalCollectionProductInfoSubscribeCode> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getProductId,productId);
        DigitalCollectionProductInfoSubscribeCode digitalCollectionProductInfoSubscribeCode = new DigitalCollectionProductInfoSubscribeCode();
        digitalCollectionProductInfoSubscribeCode.setSchedule(ProductInfoSubscribeScheduleEnum.WINING);
        return update(digitalCollectionProductInfoSubscribeCode,wrapper);
    }
    public void toWinABallotCopyResult(Long productId) {
        baseMapper.toWinABallotCopyResult(productId);
    }
    public void drawBlank(Long productId) {
        baseMapper.drawBlank(productId);
    }

    public Integer getCountByUserProductIdAndSchedule(Long userId, Long productId, ProductInfoSubscribeScheduleEnum schedule) {
        LambdaQueryWrapper<DigitalCollectionProductInfoSubscribeCode> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getUserId, userId);
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getProductId,productId);
        if(Objects.nonNull(schedule)) {
            wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getSchedule, schedule.getCode());
        }
        return baseMapper.selectCount(wrapper);
    }

    public Integer getCountByUserProductIdAndSourece(Long userId, Long productId, ProductInfoSubscribeSourceEnum schedule) {
        LambdaQueryWrapper<DigitalCollectionProductInfoSubscribeCode> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getUserId, userId);
        wrapper.eq(DigitalCollectionProductInfoSubscribeCode::getProductId,productId);
        wrapper.eq(ObjectUtil.isNotEmpty(schedule),DigitalCollectionProductInfoSubscribeCode::getSourece, schedule);
        return baseMapper.selectCount(wrapper);
    }

    public Page<DigitalCollectionProductInfoSubscribeCode> getPageByUserProductIdAndSchedule(Page page, Long userId, Long productId, ProductInfoSubscribeScheduleEnum schedule, Boolean consistenceEnd) {
        return baseMapper.getPageByUserProductIdAndSchedule(page, userId, productId, Objects.nonNull(schedule) ? schedule.getCode() : null, consistenceEnd);
    }


    public Page<SubscribeProductListVo> getByProductIdLeft(Long userId, Page page) {
        return baseMapper.getByProductIdLeft(userId, page);
    }
}
